/*-
 * $Id: Color.java 4 2010-11-04 07:39:56Z andrewbass $
 */

package com.google.code.getwrong.terminalui;

/**
 * @author Andrew ``Bass'' Shcheglov (andrewbass@gmail.com)
 * @author $Author: andrewbass $
 * @version $Revision: 4 $, $Date:: 2010-11-04 07:39:56 +0000 #$
 */
public abstract class Color {
	public static final Color BLACK = new SystemColor(0, false);

	public static final Color RED = new SystemColor(1, false);

	public static final Color GREEN = new SystemColor(2, false);

	public static final Color YELLOW = new SystemColor(3, false);

	public static final Color BLUE = new SystemColor(4, false);

	public static final Color MAGENTA = new SystemColor(5, false);

	public static final Color CYAN = new SystemColor(6, false);

	public static final Color WHITE = new SystemColor(7, false);

	/*-
	 * The next 8 system colors below will look just the same
	 * if the terminal only supports 16 colors.
	 */

	public static final Color BLACK_BRIGHT = new SystemColor(0, true);

	public static final Color RED_BRIGHT = new SystemColor(1, true);

	public static final Color GREEN_BRIGHT = new SystemColor(2, true);

	public static final Color YELLOW_BRIGHT = new SystemColor(3, true);

	public static final Color BLUE_BRIGHT = new SystemColor(4, true);

	public static final Color MAGENTA_BRIGHT = new SystemColor(5, true);

	public static final Color CYAN_BRIGHT = new SystemColor(6, true);

	public static final Color WHITE_BRIGHT = new SystemColor(7, true);

	Color() {
		// empty
	}

	/**
	 * @param terminal
	 */
	abstract int[] getForegroundAttributes(final Terminal terminal);

	/**
	 * @param terminal
	 */
	abstract int[] getBackgroundAttributes(final Terminal terminal);

	/**
	 * @author Andrew ``Bass'' Shcheglov (andrewbass@gmail.com)
	 * @author $Author: andrewbass $
	 * @version $Revision: 4 $, $Date:: 2010-11-04 07:39:56 +0000 #$
	 */
	private static final class SystemColor extends Color {
		private final int ordinal;

		private final boolean bright;

		/**
		 * @param ordinal
		 * @param bright
		 */
		SystemColor(final int ordinal, final boolean bright) {
			this.ordinal = ordinal;
			this.bright = bright;
		}

		/**
		 * @see Color#getForegroundAttributes(Terminal)
		 */
		@Override
		public int[] getForegroundAttributes(final Terminal terminal) {
			return terminal.supports256Colors()
					? new int[] {
							38,
							5,
							SystemColor.this.bright
									? SystemColor.this.ordinal + 8
									: SystemColor.this.ordinal}
					: new int[] {
							30 + SystemColor.this.ordinal};
		}

		/**
		 * @see Color#getBackgroundAttributes(Terminal)
		 */
		@Override
		public int[] getBackgroundAttributes(final Terminal terminal) {
			return terminal.supports256Colors()
					? new int[] {
							48,
							5,
							SystemColor.this.bright
									? SystemColor.this.ordinal + 8
									: SystemColor.this.ordinal}
					: new int[] {
							40 + SystemColor.this.ordinal};
		}
	}
}
